package com.yumeng.framework.auth.security.bean;

import com.yumeng.common.auth.BaseAuthInfo;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.CredentialsContainer;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

/**
 * @author wxd
 * @date 2024/10/24 13:47
 */
@Slf4j
@Getter
@Setter
public class MyUserDetails implements UserDetails, CredentialsContainer {

    private final String userId;
    private final String username;
    private final Set<GrantedAuthority> authorities;
    private final boolean accountNonExpired;
    private final boolean accountNonLocked;
    private final boolean credentialsNonExpired;
    private final boolean enabled;

    private String password;

    private BaseAuthInfo authInfo;//自定义认证信息结构，业务中使用。UserDetails结构是spring-security框架中使用。

    public MyUserDetails(BaseAuthInfo authInfo){

        this.userId = authInfo.getIdentityId();
        this.username = authInfo.getAuthKey();//登录的方式不同，此处的username可能不是真正意义上的username，也可能是手机号或者身份证号等等
        this.password = authInfo.getCredentials();

        this.accountNonExpired = !authInfo.isAccountExpired();
        this.accountNonLocked = !authInfo.isAccountLocked();
        this.credentialsNonExpired = !authInfo.isCredentialsExpired();
        this.enabled = authInfo.isEnabled();

        this.authorities = new HashSet<>();
        authInfo.getAuthorities().forEach(p-> {
            authorities.add(new SimpleGrantedAuthority(p));
        });
        this.authInfo = authInfo;
    }


    //必须实现，否在session并发控制将失效
    @Override
    public boolean equals(Object obj) {
        if (obj instanceof MyUserDetails user) {
            return this.userId.equals(user.getUserId()) && this.username.equals(user.getUsername());
        }
        return false;
    }

    @Override
    public int hashCode() {
        return this.userId.hashCode();
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(getClass().getName()).append(" [");
        sb.append("UserId=").append(this.userId).append(", ");
        sb.append("Username=").append(this.username).append(", ");
        sb.append("Password=[PROTECTED], ");
        sb.append("Enabled=").append(this.enabled).append(", ");
        sb.append("AccountNonExpired=").append(this.accountNonExpired).append(", ");
        sb.append("CredentialsNonExpired=").append(this.credentialsNonExpired).append(", ");
        sb.append("AccountNonLocked=").append(this.accountNonLocked).append(", ");
        sb.append("Granted Authorities=").append(this.authorities).append("]");
        return sb.toString();
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return this.authorities;
    }

    @Override
    public String getPassword() {
        return this.password;
    }

    @Override
    public String getUsername() {
        return this.username;
    }

    @Override
    public boolean isAccountNonExpired() {
        return this.accountNonExpired;
    }

    @Override
    public boolean isAccountNonLocked() {
        return this.accountNonLocked;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return this.credentialsNonExpired;
    }

    @Override
    public boolean isEnabled() {
        return this.enabled;
    }

    @Override
    public void eraseCredentials() {
        this.password = null;
        this.authInfo.eraseCredentials();
    }

}
